package com.example.aviatorCount.controller;

import com.example.aviatorCount.model.CalculateRequest;
import com.example.aviatorCount.model.FormulaResult;
import com.example.aviatorCount.model.SavedFormula;
import com.example.aviatorCount.service.DynamicFormulaCalculator;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 公式计算和管理控制器
 * 提供计算、保存、加载功能
 */
@Slf4j
@RestController
@RequestMapping("/api/formula")
@RequiredArgsConstructor
@CrossOrigin(origins = "*") // 允许跨域访问
public class FormulaController {

    private final DynamicFormulaCalculator calculator;
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Value("${formula.storage.path:./formulas}")
    private String formulaStoragePath;

    /**
     * 计算公式
     */
    @PostMapping("/calculate")
    public ResponseEntity<Map<String, Object>> calculateFormula(@RequestBody CalculateRequest request) {
        Map<String, Object> response = new HashMap<>();

        try {
            long startTime = System.currentTimeMillis();

            log.info("计算表达式: {}", request.getExpression());
            log.info("输入参数: {}", request.getInputs());

            // 直接使用表达式计算
            FormulaResult result = calculator.calculateExpression(request.getExpression(), request.getInputs());

            long endTime = System.currentTimeMillis();
            result.setExecutionTime(endTime - startTime);

            if (result.isSuccess()) {
                response.put("success", true);
                response.put("message", "计算成功");
                response.put("data", result);
                return ResponseEntity.ok(response);
            } else {
                response.put("success", false);
                response.put("message", result.getErrorMessage());
                return ResponseEntity.badRequest().body(response);
            }
        } catch (Exception e) {
            log.error("计算公式失败: " + request.getExpression(), e);
            response.put("success", false);
            response.put("message", "计算失败: " + e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 保存公式
     */
    @PostMapping("/save")
    public ResponseEntity<Map<String, Object>> saveFormula(@RequestBody SavedFormula formula) {
        Map<String, Object> response = new HashMap<>();
        try {
            // 设置时间戳
            long currentTime = System.currentTimeMillis();
            if (formula.getCreateTime() == null) {
                formula.setCreateTime(currentTime);
            }
            formula.setUpdateTime(currentTime);
            // 确保存储目录存在
            Path storagePath = Paths.get(formulaStoragePath);
            if (!Files.exists(storagePath)) {
                Files.createDirectories(storagePath);
            }

            // 生成文件名：公式名.json
            String fileName = sanitizeFileName(formula.getName()) + ".json";
            Path filePath = storagePath.resolve(fileName);

            // 保存到文件
            objectMapper.writeValue(filePath.toFile(), formula);

            log.info("公式已保存: {} -> {}", formula.getName(), filePath);
            response.put("success", true);
            response.put("message", "公式保存成功: " + formula.getName());
            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("保存公式失败", e);
            response.put("success", false);
            response.put("message", "保存失败: " + e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 获取所有保存的公式列表
     */
    @GetMapping("/list")
    public ResponseEntity<Map<String, Object>> getFormulaList() {
        Map<String, Object> response = new HashMap<>();
        try {
            List<SavedFormula> formulas = new ArrayList<>();
            Path storagePath = Paths.get(formulaStoragePath);
            if (Files.exists(storagePath)) {
                Files.list(storagePath).filter(path -> path.toString().endsWith(".json")).forEach(path -> {
                    try {
                        SavedFormula formula = objectMapper.readValue(path.toFile(), SavedFormula.class);
                        formulas.add(formula);
                    } catch (IOException e) {
                        log.warn("无法读取公式文件: " + path, e);
                    }
                });
            }
            response.put("success", true);
            response.put("message", "获取成功");
            response.put("data", formulas);
            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("获取公式列表失败", e);
            response.put("success", false);
            response.put("message", "获取列表失败: " + e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 加载指定公式
     */
    @GetMapping("/load/{formulaName}")
    public ResponseEntity<Map<String, Object>> loadFormula(@PathVariable String formulaName) {
        Map<String, Object> response = new HashMap<>();

        try {
            String fileName = sanitizeFileName(formulaName) + ".json";
            Path filePath = Paths.get(formulaStoragePath).resolve(fileName);

            if (!Files.exists(filePath)) {
                response.put("success", false);
                response.put("message", "公式不存在: " + formulaName);
                return ResponseEntity.badRequest().body(response);
            }

            SavedFormula formula = objectMapper.readValue(filePath.toFile(), SavedFormula.class);

            log.info("公式已加载: {}", formulaName);
            response.put("success", true);
            response.put("message", "加载成功");
            response.put("data", formula);
            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("加载公式失败: " + formulaName, e);
            response.put("success", false);
            response.put("message", "加载失败: " + e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 获取指定公式
     */
    @GetMapping("/get/{formulaName}")
    public ResponseEntity<Map<String, Object>> getFormula(@PathVariable String formulaName) {
        Map<String, Object> response = new HashMap<>();

        try {
            String fileName = sanitizeFileName(formulaName) + ".json";
            Path filePath = Paths.get(formulaStoragePath).resolve(fileName);

            if (!Files.exists(filePath)) {
                response.put("success", false);
                response.put("message", "公式不存在: " + formulaName);
                return ResponseEntity.badRequest().body(response);
            }

            SavedFormula formula = objectMapper.readValue(filePath.toFile(), SavedFormula.class);

            log.info("公式已获取: {}", formulaName);
            response.put("success", true);
            response.put("message", "获取成功");
            response.put("data", formula);
            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("获取公式失败: " + formulaName, e);
            response.put("success", false);
            response.put("message", "获取失败: " + e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 删除公式
     */
    @DeleteMapping("/delete/{formulaName}")
    public ResponseEntity<Map<String, Object>> deleteFormula(@PathVariable String formulaName) {
        Map<String, Object> response = new HashMap<>();

        try {
            String fileName = sanitizeFileName(formulaName) + ".json";
            Path filePath = Paths.get(formulaStoragePath).resolve(fileName);

            if (!Files.exists(filePath)) {
                response.put("success", false);
                response.put("message", "公式不存在: " + formulaName);
                return ResponseEntity.badRequest().body(response);
            }

            Files.delete(filePath);

            log.info("公式已删除: {}", formulaName);
            response.put("success", true);
            response.put("message", "公式删除成功: " + formulaName);
            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("删除公式失败: " + formulaName, e);
            response.put("success", false);
            response.put("message", "删除失败: " + e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 清理文件名，移除非法字符
     */
    private String sanitizeFileName(String fileName) {
        if (fileName == null || fileName.trim().isEmpty()) {
            return "unnamed_formula";
        }

        // 替换非法字符为下划线
        return fileName.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5_-]", "_").trim();
    }
}
